package edu.study.ops.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import edu.study.api.common.constants.Constants;
import edu.study.api.common.dto.BaseRespDto;
import edu.study.api.common.enums.BaseResultCodeEnum;
import edu.study.api.common.json.JsonUtils;
import edu.study.common.util.cache.Cache;
import edu.study.user.api.dto.UserDetailDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Component
@Slf4j
public class TokenCheckPreFilter extends ZuulFilter {

    //不用拦截的地址
    private List<String> paths;
    
    //拦截地址
    private String path = "/api/user/userApi/logout";

    public TokenCheckPreFilter() {
        super();
        paths = new ArrayList<>();
        paths.add("/api/user/userApi/login");
    }

    @Autowired
    private Cache cache;

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 2;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        String uri = request.getRequestURI();
        log.debug("TokenCheckPreFilter uri:{}", uri);
        PathMatcher matcher = new AntPathMatcher();
        Optional<String> optional = paths.stream().filter(t->matcher.match(t,uri)).findFirst();
        return !optional.isPresent();
    }

    @Override
    public Object run() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest httpServletRequest = requestContext.getRequest();
        String url = httpServletRequest.getRequestURI().substring(httpServletRequest.getContextPath().length());
        requestContext.getResponse().setContentType("application/json;charset=UTF-8");//TODO 
        //从header中获取token
        String token = httpServletRequest.getHeader(Constants.TOKEN);
        if (StringUtils.isEmpty(token)) {
            log.info("TokenCheckPreFilter 没有登录或者用户超时[{}]", url);
            sendMessage(requestContext);
            return null;
        }
        String cacheJson = cache.get(token);
        log.info("TokenCheckPreFilter cacheJson={}", cacheJson);
        if (StringUtils.isEmpty(cacheJson)) {
            log.info("TokenCheckPreFilter 用户超时[{}]", url);
            sendMessage(requestContext);
            return null;
        }
        UserDetailDto userDetailDto = JsonUtils.fromJson(cacheJson, UserDetailDto.class);
        if(userDetailDto==null) {
        	log.info("TokenCheckPreFilter 用户超时[{}]", url);
            sendMessage(requestContext);
            return null;
        }
        
        //退出的逻辑直接这里,不用再去调用户系统
        if(path.equals(url)) {
        	cache.del(token);
            cache.del(userDetailDto.getUserNo());
            
            BaseRespDto result = new BaseRespDto();
    		requestContext.setResponseStatusCode(HttpServletResponse.SC_OK);
    		requestContext.setResponseBody(JsonUtils.toJson(result));
    		requestContext.setSendZuulResponse(false);
            return null;
        }
        
        requestContext.addZuulRequestHeader(Constants.CURRENT_USER, cacheJson);
        //todo 这个地方暂时拿不到body
        String responseBody = requestContext.getResponseBody();
        if (!StringUtils.isEmpty(responseBody)) {
            if (responseBody.length() < 1000) {
                log.info("ops调用下游系统 begin, url={}, body={}", url, responseBody);
            } else {
                log.info("ops调用下游系统 begin, url={}, body={}...", url, responseBody.substring(0, 1000));
            }
        } else {
            log.info("ops调用下游系统 begin, url={}, body参数空", url);
        }
        return null;
    }

	private void sendMessage(RequestContext requestContext) {
		BaseRespDto result = new BaseRespDto();
		result.setResultFail(BaseResultCodeEnum.TIME_OUT);
		requestContext.setResponseStatusCode(HttpServletResponse.SC_UNAUTHORIZED);
		requestContext.setResponseBody(JsonUtils.toJson(result));
		requestContext.setSendZuulResponse(false);
	}
}